package smartgrid.output;

public class ProsumerDSOutputEntity extends AbstractEntity {
	
	public enum Field {
		CYCLE("cycle", DataType.INTEGER),
		PROSUMER_ID("prosumer", DataType.INTEGER),
		WEALTH("wealth", DataType.DOUBLE),
		SELF_INTEREST("self_interest", DataType.DOUBLE),
		NORM_STATUS("normStatus", DataType.STRING),
		NORM_SALIENCE("normSalience", DataType.DOUBLE),
		CONSUME_ESTIMATION("consume_estimation", DataType.DOUBLE),
		GENERATE_ESTIMATION("generate_estimation", DataType.DOUBLE),
		CONSUME_REAL("consume_real", DataType.DOUBLE),
		GENERATE_REAL("generate_real", DataType.DOUBLE),
		CONSUME_ACCURACY("consume_accuracy", DataType.DOUBLE),
		GENERATE_ACCURACY("generate_accuracy", DataType.DOUBLE),
		SUPPLIER("supplier", DataType.BOOLEAN),
		BUYER("buyer", DataType.BOOLEAN),
		BALANCE("energy_balance", DataType.DOUBLE),
		PROVIDER_BUY("buy_from_provider", DataType.DOUBLE),
		PROVIDER_PAID("paid_to_provider", DataType.DOUBLE),
		PROVIDER_SELL("sell_to_provider", DataType.DOUBLE),
		PROVIDER_RECEIVED("received_from_provider", DataType.DOUBLE),
		SANCTIONING_COST("sanctioning_cost", DataType.DOUBLE),
		A_PUN_SANCTION("a_pun_sanction", DataType.INTEGER),
		A_PUN_INFO_SANCTION("a_pun-info_sanction", DataType.INTEGER),
		A_INFO_SANCTION("a_info_sanction", DataType.INTEGER),
		R_PUN_SANCTION("r_pun_sanction", DataType.INTEGER),
		R_PUN_INFO_SANCTION("r_pun-info_sanction", DataType.INTEGER),
		R_INFO_SANCTION("r_info_sanction", DataType.INTEGER),
		O_PUN_SANCTION("o_pun_sanction", DataType.INTEGER),
		O_PUN_INFO_SANCTION("o_pun-info_sanction", DataType.INTEGER),
		O_INFO_SANCTION("o_info_sanction", DataType.INTEGER);
		
		private String		name;
		
		private DataType	type;
		
		
		Field(String name, DataType type) {
			this.name = name;
			this.type = type;
		}
		
		
		public String getName() {
			return this.name;
		}
		
		
		public DataType getType() {
			return this.type;
		}
	}
	
	private String		separator;
	
	private Object[]	entity;
	
	
	public ProsumerDSOutputEntity(int id, String separator) {
		super(id);
		this.separator = separator;
		this.entity = new Object[Field.values().length];
		
		this.entity[Field.CYCLE.ordinal()] = 0;
		this.entity[Field.PROSUMER_ID.ordinal()] = 0;
		this.entity[Field.WEALTH.ordinal()] = 0.0;
		this.entity[Field.SELF_INTEREST.ordinal()] = 0.0;
		this.entity[Field.NORM_STATUS.ordinal()] = "";
		this.entity[Field.NORM_SALIENCE.ordinal()] = 0.0;
		this.entity[Field.CONSUME_ESTIMATION.ordinal()] = 0.0;
		this.entity[Field.GENERATE_ESTIMATION.ordinal()] = 0.0;
		this.entity[Field.CONSUME_REAL.ordinal()] = 0.0;
		this.entity[Field.GENERATE_REAL.ordinal()] = 0.0;
		this.entity[Field.CONSUME_ACCURACY.ordinal()] = 0.0;
		this.entity[Field.GENERATE_ACCURACY.ordinal()] = 0.0;
		this.entity[Field.SUPPLIER.ordinal()] = false;
		this.entity[Field.BUYER.ordinal()] = false;
		this.entity[Field.BALANCE.ordinal()] = 0.0;
		this.entity[Field.PROVIDER_BUY.ordinal()] = 0.0;
		this.entity[Field.PROVIDER_PAID.ordinal()] = 0.0;
		this.entity[Field.PROVIDER_SELL.ordinal()] = 0.0;
		this.entity[Field.PROVIDER_RECEIVED.ordinal()] = 0.0;
		this.entity[Field.SANCTIONING_COST.ordinal()] = 0.0;
		this.entity[Field.A_PUN_SANCTION.ordinal()] = 0;
		this.entity[Field.A_PUN_INFO_SANCTION.ordinal()] = 0;
		this.entity[Field.A_INFO_SANCTION.ordinal()] = 0;
		this.entity[Field.R_PUN_SANCTION.ordinal()] = 0;
		this.entity[Field.R_PUN_INFO_SANCTION.ordinal()] = 0;
		this.entity[Field.R_INFO_SANCTION.ordinal()] = 0;
		this.entity[Field.O_PUN_SANCTION.ordinal()] = 0;
		this.entity[Field.O_PUN_INFO_SANCTION.ordinal()] = 0;
		this.entity[Field.O_INFO_SANCTION.ordinal()] = 0;
	}
	
	
	@Override
	public void setValue(String fieldStr, Object value) {
		
		Field field = Field.valueOf(fieldStr);
		
		if (field.getType().equals(DataType.BOOLEAN)) {
			this.entity[field.ordinal()] = (Boolean) value;
			
		} else if (field.getType().equals(DataType.DOUBLE)) {
			this.entity[field.ordinal()] = (Double) value;
			
		} else if (field.getType().equals(DataType.INTEGER)) {
			this.entity[field.ordinal()] = (Integer) value;
			
		} else if (field.getType().equals(DataType.STRING)) {
			this.entity[field.ordinal()] = (String) value;
			
		}
	}
	
	
	@Override
	public Object getValue(String fieldStr) {
		return this.entity[Field.valueOf(fieldStr).ordinal()];
	}
	
	
	@Override
	public String getLine() {
		String line = new String();
		
		Object value;
		for(Field field : Field.values()) {
			value = this.entity[field.ordinal()];
			if (value == null) {
				value = (String) "";
			}
			line += value + this.separator;
		}
		line = line.substring(0, line.length() - 1);
		
		return line;
	}
	
	
	@Override
	public String getHeader() {
		String header = new String();
		
		for(Field field : Field.values()) {
			header += field.getName() + this.separator;
		}
		header = header.substring(0, header.length() - 1);
		
		return header;
	}
}